package com.zbkj.crmeb.payment.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;

import javax.annotation.Resource;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import com.utils.SpringBeanUtil;
import com.utils.monitor.DingMsgEnum;
import com.utils.monitor.DingTalkMsgUtil;
import com.zbkj.crmeb.store.service.*;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.constants.Constants;
import com.crmeb.core.exception.CrmebException;
import com.utils.DateUtil;
import com.zbkj.crmeb.agent.model.AgentAccount;
import com.zbkj.crmeb.agent.model.AgentFreezeBill;
import com.zbkj.crmeb.agent.service.AgentAccountFlowService;
import com.zbkj.crmeb.agent.service.AgentAccountService;
import com.zbkj.crmeb.agent.service.AgentFreezeBillService;
import com.zbkj.crmeb.bill.service.MerFreezeBillService;
import com.zbkj.crmeb.chant.model.ChannelMerchant;
import com.zbkj.crmeb.chant.model.ChannelMerchantAccount;
import com.zbkj.crmeb.chant.service.IChannelMerchantAccountService;
import com.zbkj.crmeb.chant.service.IChannelMerchantService;
import com.zbkj.crmeb.enums.AccountFlowTypeEnum;
import com.zbkj.crmeb.enums.BarCodeEnum;
import com.zbkj.crmeb.enums.OrderTradeTypeEnum;
import com.zbkj.crmeb.front.response.UserRechargePaymentResponse;
import com.zbkj.crmeb.marketing.service.StoreCouponUserService;
import com.zbkj.crmeb.merchant.api.service.MerOrderService;
import com.zbkj.crmeb.order.ChannelStoreOrderThreadPool;
import com.zbkj.crmeb.order.StoreOrderFactory;
import com.zbkj.crmeb.order.channel.JkyStoreOrderServiceImpl;
import com.zbkj.crmeb.payment.service.OrderPayService;
import com.zbkj.crmeb.payment.service.PayService;
import com.zbkj.crmeb.payment.vo.wechat.AttachVo;
import com.zbkj.crmeb.payment.vo.wechat.CreateOrderResponseVo;
import com.zbkj.crmeb.payment.vo.wechat.PayParamsVo;
import com.zbkj.crmeb.payment.wechat.WeChatPayService;
import com.zbkj.crmeb.sms.service.SmsService;
import com.zbkj.crmeb.store.dao.StoreOrderInfoDao;
import com.zbkj.crmeb.store.model.StoreAccountInfo;
import com.zbkj.crmeb.store.model.StoreOrder;
import com.zbkj.crmeb.store.model.StoreOrderInfo;
import com.zbkj.crmeb.store.model.StoreProductAttrValue;
import com.zbkj.crmeb.store.request.RetailShopRequest;
import com.zbkj.crmeb.store.response.StoreCartResponse;
import com.zbkj.crmeb.store.utilService.OrderUtils;
import com.zbkj.crmeb.store.vo.StoreOrderInfoVo;
import com.zbkj.crmeb.system.service.MessageConfigService;
import com.zbkj.crmeb.user.model.User;
import com.zbkj.crmeb.user.model.UserBill;
import com.zbkj.crmeb.user.service.UserBillService;
import com.zbkj.crmeb.user.service.UserService;
import com.zbkj.crmeb.wechat.service.TemplateMessageService;
import com.zbkj.crmeb.wechat.service.WeChatService;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;


/**
 * <p>
 * 支付类
 * </p>
 *
 * @author Mr.Zhang
 * @since 2020-04-10
 */
@EqualsAndHashCode(callSuper = true)
@Data
@Service
@Slf4j
public class OrderPayServiceImpl extends PayService implements OrderPayService {
    private static final Logger logger = LoggerFactory.getLogger(OrderPayServiceImpl.class);

    @Autowired
    private StoreOrderService storeOrderService;
    @Autowired
    private StoreOrderStatusService storeOrderStatusService;
    @Autowired
    private StoreOrderInfoService storeOrderInfoService;
    @Lazy
    @Autowired
    private WeChatPayService weChatPayService;
    @Autowired
    private TemplateMessageService templateMessageService;
    @Autowired
    private UserBillService userBillService;
    @Autowired
    private UserService userService;
    @Autowired
    private StoreProductCouponService storeProductCouponService;
    @Autowired
    private StoreCouponUserService storeCouponUserService;
    @Autowired
    private WeChatService weChatService;
    //订单类
    private StoreOrder order;
    //支付类参参数
    private PayParamsVo payParamsVo;
    @Autowired
    private RetailShopService retailShopService;
    @Autowired
    StoreOrderFactory storeOrderFactory;
    @Autowired
    private StoreAccountInfoService storeAccountInfoService;
    @Autowired
    private UserCommissionService userCommissionService;
    @Autowired
    private IChannelMerchantAccountService channelMerchantAccountService;
    @Autowired
    private MessageConfigService messageConfigService;
    @Autowired
    private MerFreezeBillService merFreezeBillService;
    @Autowired
    private AccountFlowService accountFlowService;
    @Autowired
    private SmsService smsService;
    @Autowired
    private AgentAccountService agentAccountService;
    @Autowired
    private AgentFreezeBillService agentFreezeBillService;
    @Autowired
    private AgentAccountFlowService agentAccountFlowService;
    @Autowired
    private JkyStoreOrderServiceImpl jkyStoreOrderService;
    @Autowired
    private OrderUtils orderUtils;
    @Resource
    private StoreOrderInfoDao storeOrderInfoDao;
    @Autowired
    private StoreProductService storeProductService;
    @Autowired
    private StoreProductReplyService storeProductReplyService;
    @Autowired
    private IChannelMerchantService channelMerchantService;
    @Autowired
    private PurchaseGoodsService purchaseGoodsService;
    @Autowired
    StoreSaleAnalysisService storeSaleAnalysisService;
    @Lazy
    @Autowired
    MerOrderService merOrderService;
    @Autowired
    private StoreOrderGroupInfoService storeOrderGroupInfoService;

    /**
     * 订单支付
     * @param orderId Integer 订单号
     * @param fromType String 客户端类型
     * @author Mr.Zhang
     * @since 2020-06-22
     * @return PayResponseVo
     */
    @Override
    public CreateOrderResponseVo payOrder(Integer orderId, String fromType, String clientIp) {
        // todo 这里需要根据 fromType 参数直接替换当前支付方式，
        CreateOrderResponseVo responseVo = new CreateOrderResponseVo();
        StoreOrder storeOrder = storeOrderService.getById(orderId);
        setOrder(storeOrder);
        //针对order进行验证, 是否未支付验证
        beforePay();
        try{
            switch (storeOrder.getPayType()){
                case Constants.PAY_TYPE_WE_CHAT: // 微信支付
                case Constants.PAY_TYPE_WE_CHAT_FROM_NATIVE: // 扫码支付
                case Constants.PAY_TYPE_WE_CHAT_FROM_PROGRAM:
                    PayParamsVo payParamsVoRouter = getPayParamsVo(fromType, clientIp, storeOrder);
                    payParamsVoRouter.setMerId(storeOrder.getMerId());
                    responseVo = weChatPayService.create(payParamsVoRouter);// 构造下单类
                    responseVo.setMerId(storeOrder.getMerId());
                    UserRechargePaymentResponse response = weChatService.response(responseVo);
                    responseVo.setTransJsConfig(response);
                    break;
                case Constants.PAY_TYPE_ALI_PAY: //支付宝
                    throw new CrmebException("支付宝未接入支付");
                case Constants.PAY_TYPE_OFFLINE: //线下支付
                    responseVo = responseVo.setResultCode("1");
                    break;
//                    throw new CrmebException("线下支付未开通");
                case Constants.PAY_TYPE_YUE: //余额支付 判断余额支付成功CreateOrderResponseVo.ResultCode = 1;
                    if (storeOrderService.yuePay(storeOrder, userService.getInfo())){
                        responseVo = responseVo.setResultCode("1");
                    }
                    break;
            }
            // 清除缓存的订单信息

        }catch (Exception e){
            logger.error("订单支付失败, order:{}",orderId,e);
            throw new CrmebException("订单支付失败！"+e.getMessage());
        }
        return responseVo;
    }
    
    /**
     * 只生成支付二维码, 不走流程
     * TODO 不可用方法!!!!
     * @author daigb
     * @date:  2022-12-05 10:23
     */
    @Override
    public CreateOrderResponseVo payOrder2(String orderId, BigDecimal price) {
    	CreateOrderResponseVo responseVo = new CreateOrderResponseVo();
    	try{
			PayParamsVo payParamsVoRouter = new PayParamsVo(
    				orderId, "native", "60.12.139.34", "测试商品", price, 1,
                    new AttachVo(Constants.SERVICE_PAY_TYPE_ORDER, 1)
            );
			payParamsVoRouter.setMerId(18);
			responseVo = weChatPayService.create(payParamsVoRouter);// 构造下单类
			responseVo.setMerId(18);
			UserRechargePaymentResponse response = weChatService.response(responseVo);
			responseVo.setTransJsConfig(response);
    	}catch (Exception e){
    		logger.error("订单支付失败, order:{}",orderId,e);
    		throw new CrmebException("订单支付失败！"+e.getMessage());
    	}
    	
    	return responseVo;
    }


    /**
     *  组装微信支付参数
     * @param fromType
     * @param clientIp
     * @param storeOrder
     * @return
     */
    private PayParamsVo getPayParamsVo(String fromType, String clientIp, StoreOrder storeOrder) {
        //支付需要的参数
        return new PayParamsVo(
                storeOrder.getOrderId(),
                fromType,
                clientIp,
                getProductName(),
                storeOrder.getPayPrice(),
                storeOrder.getUid(),
                new AttachVo(Constants.SERVICE_PAY_TYPE_ORDER, storeOrder.getUid())
        );
    }


    /**
     * 支付之前
     * @author Mr.Zhang
     * @since 2020-06-22
     */
    private void beforePay() {
        checkOrderUnPay();
    }


    /**
     * 支付成功
     * @param orderId String 订单号
     * @param userId Integer 用户id
     * @param payType String 支付类型
     * @author Mr.Zhang
     * @since 2020-06-22
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class, CrmebException.class})
    public boolean success(String orderId, Integer userId, String payType , String outOrderId, String backParam) {
        log.info("[支付成功的异步通知] 入参为：{},{},{},{},{}",orderId, userId, payType, outOrderId, backParam);
        try{
            StoreOrder storeOrder = new StoreOrder();
            storeOrder.setOrderId(orderId);
            storeOrder.setUid(userId);
            storeOrder = storeOrderService.getInfoByEntity(storeOrder);
            // TODO outOrderId
            storeOrder.setOutOrderId(outOrderId);
            storeOrder.setBackParam(backParam);
            setOrder(storeOrder);
            if(!checkOrderUnPay()) {
            	log.error("--------------- 订单已处理: {} ---------------", outOrderId);
            	return true;
            }

            try {
                OrderPayService bean = SpringBeanUtil.getBean(OrderPayService.class);
                bean.afterPaySuccess(getOrder());
            }catch (Exception e){
                log.error("订单支付回调后置任务处理异常: ",e);
            }


            return true;
        }catch (Exception e){
            log.error("订单支付回调失败了:" + e);
            throw new CrmebException("订单支付回调失败，" + e.getMessage());
        }
    }


    /**
     * 支付成功之后, 需要事物处理
     * @author Mr.Zhang
     * @since 2020-06-22
     * @return
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class, CrmebException.class})
    public void afterPaySuccessTest(Integer id){
        StoreOrder storeOrder = storeOrderService.getById(id);
        // 子订单
        List<StoreOrderInfo> storeOrderInfoList = storeOrderInfoService.list(Wrappers.lambdaQuery(StoreOrderInfo.class).eq(StoreOrderInfo::getOrderId, id));

        // 佣金
        // TODO
        userCommissionService.freezeUserCommissionTest(storeOrder, storeOrderInfoList);

        /***** end *****/
    }

    /**
     * 支付成功之后, 需要事物处理
     * @author Mr.Zhang
     * @since 2020-06-22
     * @return
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class, CrmebException.class})
    public void afterPaySuccess(StoreOrder storeOrder){
        log.info("拼团活动的团长佣金 afterPaySuccess");
        try {
            // 子订单
            List<StoreOrderInfo> storeOrderInfoList = storeOrderInfoService.list(Wrappers.lambdaQuery(StoreOrderInfo.class).eq(StoreOrderInfo::getOrderId, storeOrder.getId()));

            // 更新订单状态
            orderUpdate(storeOrder,storeOrderInfoList);

            // 订单日志
            orderStatusCreate(storeOrder);

            // 返佣订单生成
            //userBillCreate(storeOrder);

            // 下发模板通知
            pushTempMessage(storeOrder);

            // 购买成功后根据配置送优惠券
            autoSendCoupons(storeOrder);

            // 更新用户下单数量
            updateUserPayCount(storeOrder);

            // 增加经验、积分
            //updateFounds(storeOrder);
            boolean leaderResult = false;
            try {
                // 拼团活动的团长佣金
                leaderResult = userCommissionService.freezeUserCommissionV2(storeOrder, storeOrderInfoList);
                // 佣金
                if(!leaderResult) {
                    userCommissionService.freezeUserCommission(storeOrder, storeOrderInfoList, leaderResult);
                }

            }catch (Exception e){
                logger.error("拼团活动的团长佣金计算错误，{}", e.fillInStackTrace());
            }


            // 新增账户明细表
            addAccountInfo(storeOrder);

            // 更新商户冻结余额
            updateMerchantFreezeAccount(storeOrder, storeOrderInfoList);

            /***** 下属方法都为异步执行 *****/

            // 分账业务(汇付聚合支付专属)(异步)
//        merOrderService.transDivByOrder(storeOrder, storeOrderInfoList);

            // 发短信(异步)
            // TODO
            smsService.sendCreateOrderMessage();

            // 记录商品支付数量(异步)
            merOrderService.saveAddPurchaseNumber(storeOrder,storeOrderInfoList);

            // 转云仓自建订单自动生成采购单
            // convertPushGood(storeOrder, storeOrderInfoList);

            // 推送订单到商户绑定的供应商(异步)
            merOrderService.pushOrderByJky(storeOrder);

            // 拼团订单生成拼团信息
            if (Objects.nonNull(storeOrder.getActivityGroupId())){
                storeOrderGroupInfoService.startGroup(storeOrder, storeOrderInfoList);
            }

            /***** end *****/
        }catch (Exception e){
            log.error("支付成功后置任务处理异常: ",e);
            log.error("支付成功后置任务处理入参：{}",JSON.toJSONString(storeOrder));
            DingTalkMsgUtil.sendMsg(DingMsgEnum.ORDER_PAY,"支付成功后置任务处理异常,orderId:"+storeOrder.getOrderId());
            throw new RuntimeException(e);
        }


    }
    
    /**
     * 更新商户冻结余额
     * @param storeOrder
     */
    private void updateMerchantFreezeAccount(StoreOrder storeOrder,List<StoreOrderInfo> storeOrderInfoList) {
        //冻结金额
        BigDecimal amountFrozen = BigDecimal.ZERO,
                firstAgentFrozen = BigDecimal.ZERO,
                secondAgentFrozen = BigDecimal.ZERO;
        Integer firstAgentId = null,
                secondAgentId = null;

        //支付类型 null余额支付  true平台支付   false商家支付
        Boolean payType = orderUtils.getPayType(storeOrder.getPayType());

        //扣除商户可用余额集合
        List<BigDecimal> deductAccountList = new ArrayList<>();
        //异常订单集合
        List<Integer> abnormalList = new ArrayList<>();
        for (StoreOrderInfo storeOrderInfo : storeOrderInfoList) {
            StoreCartResponse storeCartResponse = JSON.parseObject(storeOrderInfo.getInfo(), StoreCartResponse.class);
            StoreProductAttrValue attrInfo = storeCartResponse.getProductInfo().getAttrInfo();
            //订单来源
            if(storeOrderInfo.getIsEurope()==1){
                //自建订单
                amountFrozen = amountFrozen.add(attrInfo.getPrice());
            }else {
                firstAgentId = attrInfo.getFirstAgentId();
                secondAgentId = attrInfo.getSecondAgentId();
                //服务商
                if(attrInfo.getSecondAgentCost() != null && attrInfo.getFirstAgentCost() != null){
                    //二级利润
                    secondAgentFrozen = secondAgentFrozen.add(attrInfo.getCost().subtract(attrInfo.getSecondAgentCost()));
                    //一级利润
                    firstAgentFrozen = firstAgentFrozen.add(attrInfo.getSecondAgentCost().subtract(attrInfo.getFirstAgentCost()));
                }else if(attrInfo.getSecondAgentCost() == null && attrInfo.getFirstAgentCost() != null){
                    //一级利润
                    firstAgentFrozen = firstAgentFrozen.add(attrInfo.getCost().subtract(attrInfo.getFirstAgentCost()));
                }
                //平台支付
                if(BooleanUtils.isTrue(payType)){
                    //用户支付金额-成本价-运税费  = 商户盈利
                    BigDecimal profit = attrInfo.getPaidPrice().subtract(attrInfo.getCost()).subtract(attrInfo.getTaxAndSecondPrice());
                    if(profit.compareTo(BigDecimal.ZERO)<0){
                        deductAccountList.add(profit);
                        abnormalList.add(storeOrderInfo.getId());
                    }else {
                        amountFrozen = amountFrozen.add(profit);
                    }
                }else {
                    deductAccountList.add((attrInfo.getCost().add(attrInfo.getTaxAndSecondPrice())).negate());
                    abnormalList.add(storeOrderInfo.getId());
                }
            }
        }

        try {
            // 发送消息通知和短信提醒
            messageConfigService.sendWarningMessage(storeOrder.getMerId());
        }catch (Exception e){
            log.error("发送消息通知和短信提醒报错：{}", e);
        }
        ChannelMerchantAccount merchantAccount = new ChannelMerchantAccount();
        merchantAccount.setMerId(storeOrder.getMerId())
                .setTotalMoney(storeOrder.getPayPrice());
        BigDecimal reduce = deductAccountList.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        //判断异常订单
        ChannelMerchantAccount channelMerchantAccount = channelMerchantAccountService.getOne(Wrappers.<ChannelMerchantAccount>lambdaQuery().eq(ChannelMerchantAccount :: getMerId, storeOrder.getMerId()));
        if(channelMerchantAccount.getAccount().compareTo(reduce.negate())<0){
            //标记异常订单 系统扣除可用余额时，余额不足，订单异常
            storeOrderService.update(Wrappers.lambdaUpdate(StoreOrder.class).set(StoreOrder::getAbnormal,1).eq(StoreOrder::getId,storeOrder.getId()));
            storeOrderInfoService.update(Wrappers.lambdaUpdate(StoreOrderInfo.class).set(StoreOrderInfo::getAbnormal,1).eq(StoreOrderInfo::getOrderId,storeOrder.getId()).in(CollectionUtils.isNotEmpty(abnormalList),StoreOrderInfo::getId,abnormalList));
            storeOrderStatusService.createLog(storeOrder.getId(),storeOrder.getOrderId(), "abnormal_order", "系统扣除可用余额时，余额不足，订单异常");
        }else {
            ChannelMerchantAccount merchant = new ChannelMerchantAccount();
            merchant.setMerId(storeOrder.getMerId());
            for (BigDecimal deductAccount : deductAccountList) {
                merchant.setAccount(deductAccount);
                // TODO
                channelMerchantAccountService.calcMoney(merchant);
                log.info("用户支付成功,减少商户可用金额, 商户: {}, 金额: {}", storeOrder.getMerId(), deductAccount.negate());
                accountFlowService.saveAccountFlow(storeOrder.getMerId(),storeOrder.getId(),null,null,
                        AccountFlowTypeEnum.PRODUCT,deductAccount,null,null,BooleanUtils.isTrue(payType) ? "售价低于成本价" : "成本价");
            }
        }

        if(payType == null){
            //冻结账单记录
            merFreezeBillService.addFreezeBill(storeOrder,BigDecimal.ZERO);
            //余额支付 冻结+0
            merchantAccount.setFreezeAccount(BigDecimal.ZERO);
            channelMerchantAccountService.calcMoney(merchantAccount);
            //记录商户流水操作
            accountFlowService.saveAccountFlow(storeOrder.getMerId(),storeOrder.getId(),null,null,
                    AccountFlowTypeEnum.PRODUCT,null,null,BigDecimal.ZERO,"购买商品");
        }else if(payType) {
            merFreezeBillService.addFreezeBill(storeOrder,amountFrozen);
            //平台支付 + 冻结金额
            merchantAccount.setFreezeAccount(amountFrozen);
            // TODO
            channelMerchantAccountService.calcMoney(merchantAccount);
            //记录商户流水操作
            accountFlowService.saveAccountFlow(storeOrder.getMerId(),storeOrder.getId(),null,null,
                    AccountFlowTypeEnum.PRODUCT,null,null,amountFrozen,"购买商品");
        }else {
            //商家支付  + 微信收款金额
            merchantAccount.setWithdrawAccount(storeOrder.getPayPrice());
            channelMerchantAccountService.calcMoney(merchantAccount);
            //记录商户流水操作
            accountFlowService.saveAccountFlow(storeOrder.getMerId(),storeOrder.getId(),null,null,
                    AccountFlowTypeEnum.PRODUCT,null,storeOrder.getPayPrice(),null,"购买商品");
        }
        //服务商冻结金额
        if(secondAgentId != null){
            agentFreeze(storeOrder, secondAgentFrozen, secondAgentId);
        }
        if(firstAgentId != null){
            agentFreeze(storeOrder, firstAgentFrozen, firstAgentId);
        }
    }

    private void agentFreeze(StoreOrder storeOrder, BigDecimal agentFrozen, Integer agentId) {
        AgentAccount agentAccount = new AgentAccount();
        agentAccount.setAgentId(agentId)
                .setTotalMoney(storeOrder.getPayPrice())
                .setFreezeAccount(agentFrozen);
        agentAccountService.calcMoney(agentAccount);
        log.info("用户支付成功,增加服务商冻结金额, 服务商: {}, 金额: {}", agentId, agentFrozen);
        AgentFreezeBill agentFreezeBill = new AgentFreezeBill();
        agentFreezeBill.setAgentId(agentId)
                .setOrderId(storeOrder.getId())
                .setAmountFrozen(agentFrozen)
                .setFrozen(0);
        agentFreezeBillService.save(agentFreezeBill);
        //记录服务商流水操作
        agentAccountFlowService.saveAccountFlow(agentId,storeOrder.getId(),null,null,
                AccountFlowTypeEnum.PRODUCT,null,agentFrozen,"购买商品");
    }

    private void addAccountInfo(StoreOrder storeOrder){
        User user = userService.getById(storeOrder.getUid());
        StoreAccountInfo info = new StoreAccountInfo();
        info.setOrderId(storeOrder.getOrderId());
        info.setUid(storeOrder.getUid());
        info.setOutOrderId(storeOrder.getOutOrderId());
        info.setRealName(user.getNickname());
        info.setNowMoney(user.getNowMoney());
        info.setTradeType(OrderTradeTypeEnum.CONSUME.getType());
        info.setTradePrice(storeOrder.getPayPrice());
        info.setPayType(storeOrder.getPayType());
        if(Constants.PAY_TYPE_WE_CHAT.equals(storeOrder.getPayType())){
            info.setIsAccount(0);
        }
        info.setRemark("消费"+storeOrder.getPayPrice()+"购买商品");
        storeAccountInfoService.save(info);
    }

    /**
     * 支付成功之后 - 更新订单状态
     * @author Mr.Zhang
     * @since 2020-07-01
     */
    private void orderUpdate(StoreOrder storeOrder,List<StoreOrderInfo> storeOrderInfoList) {
        boolean flag = false;
        //查询商户信息
        ChannelMerchant channelMerchant = channelMerchantService.getById(storeOrder.getMerId());
        for (StoreOrderInfo storeOrderInfo : storeOrderInfoList) {
            storeOrderInfo.setStatus( Constants.ORDER_STATUS_H5_CONFIRM);
            if (Objects.isNull(storeOrder.getActivityGroupId())){
                if(Objects.equals(storeOrderInfo.getIsEurope(),1) && Objects.equals(channelMerchant.getAutoConfirm(),1)){
                    flag = true;
                    storeOrderInfo.setStatus( Constants.ORDER_STATUS_H5_NOT_SHIPPED);
                }
            }
        }
        storeOrder.setActivityId(storeOrder.getActivityGroupId());
        //修改订单状态
        StoreOrder storeOrderUpdate = new StoreOrder();
        storeOrderUpdate.setOrderId(storeOrder.getOrderId());
        storeOrderUpdate.setId(storeOrder.getId());
        storeOrderUpdate.setPaid(true);
        storeOrderUpdate.setStatus(flag ? Constants.ORDER_STATUS_H5_NOT_SHIPPED : Constants.ORDER_STATUS_H5_CONFIRM);
        storeOrderUpdate.setPayType(storeOrder.getPayType());
        storeOrderUpdate.setPayTime(DateUtil.nowDateTime());
        storeOrderUpdate.setMark(storeOrder.getMark());
        storeOrderUpdate.setBackParam(storeOrder.getBackParam());
        storeOrderUpdate.setOutOrderId(storeOrder.getOutOrderId());
        storeOrderUpdate.setReceiptVoucher(storeOrder.getReceiptVoucher());
        storeOrderUpdate.setActivityId(storeOrder.getActivityGroupId());
        storeOrderService.updateByEntity(storeOrderUpdate);
        //修改子订单状态
        storeOrderInfoService.updateBatchById(storeOrderInfoList);
    }

    /**
     * 支付成功之后 - 订单日志(添加订单支付记录)
     * @author Mr.Zhang
     * @since 2020-07-01
     */
    private void orderStatusCreate(StoreOrder storeOrder) {
        storeOrderStatusService.createLog(storeOrder.getId(),storeOrder.getOrderId(), Constants.ORDER_LOG_PAY_SUCCESS, Constants.ORDER_LOG_MESSAGE_PAY_SUCCESS);
    }

    /**
     * 支付成功之后 - 返佣订单生成
     * @param storeOrder
     */
    private void userBillCreate(StoreOrder storeOrder) {
       try {
            Integer fristSpreadUid = null;
            Integer secondSpreadUid = null;

            //当前下单用户的信息
            Integer uid = storeOrder.getUid();
            User user = userService.getById(uid);

            //一级推广人:当前下单用户的推广人
            if (ObjectUtils.isNotEmpty(user)){
                fristSpreadUid = user.getSpreadUid();
            }

            //二级推广人:一级推广人的推广人
            if (null != fristSpreadUid){
                User secondUser = userService.getById(fristSpreadUid);
                if (ObjectUtils.isNotEmpty(secondUser)){
                    secondSpreadUid = secondUser.getSpreadUid();
                }
            }

            //获取分销配置
            RetailShopRequest retailShop = retailShopService.getManageInfo();

            //一级返佣比例
            String storeBrokerageRatio = retailShop.getStoreBrokerageRatio();

            //二级返佣比例
            String storeBrokerageTwo = retailShop.getStoreBrokerageTwo();

            //冻结天数
            String extractTime =  retailShop.getExtractTime();

            //一级推广人返佣订单生成
            createStoreBrokerage(fristSpreadUid, storeBrokerageRatio, extractTime, storeOrder);

            //二级推广人返佣订单生成
            createStoreBrokerage(secondSpreadUid, storeBrokerageTwo, extractTime, storeOrder);
        }catch (Exception e){
            throw new CrmebException("返佣订单生成异常" + e);
        }
    }

    /**
     * 返佣订单生成
     * @param spreadUid
     * @param brokerageRatio
     */
    private void createStoreBrokerage(Integer spreadUid, String brokerageRatio, String extractTime, StoreOrder storeOrder) {
        if (null != spreadUid){

            //冻结时间 = 当前时间 + 冻结天数
            Date freezeTime = DateUtil.nowDateTime();
            if (StringUtils.isNotBlank(extractTime)&& NumberUtils.isDigits(extractTime)){
                freezeTime = DateUtils.addDays(DateUtil.nowDateTime(),Integer.parseInt(extractTime));
            }

            //返佣比例
            BigDecimal storeBrokerageRatioDec = new BigDecimal(0);
            if (StringUtils.isNotBlank(brokerageRatio)){
                storeBrokerageRatioDec = new BigDecimal(brokerageRatio).multiply(new BigDecimal(0.01).setScale(2,BigDecimal.ROUND_HALF_DOWN));
            }

            //支付金额
            BigDecimal payPrice = storeOrder.getPayPrice();
            //运费
            BigDecimal payPostage = storeOrder.getPayPostage();
            //商品金额
            BigDecimal productPrice = payPrice.subtract(payPostage);

            //佣金 = 商品金额 * 返佣比例
            if (null != productPrice&& null != storeBrokerageRatioDec) {
                BigDecimal number = productPrice.multiply(storeBrokerageRatioDec);
                addUserBill(spreadUid, number, freezeTime, storeOrder);
            }

        }
    }

    /**
     * 生成用户推广订单
     */
    private void addUserBill(Integer uid, BigDecimal number, Date freezeTime, StoreOrder storeOrder) {
        UserBill userBill = new UserBill();
        userBill.setUid(uid);
        userBill.setPm(1);
        userBill.setLinkId(storeOrder.getId().toString());
        userBill.setTitle("购买商品");
        userBill.setCategory(Constants.USER_BILL_CATEGORY_BROKERAGE_PRICE);
        userBill.setType(Constants.USER_BILL_TYPE_PAY_PRODUCT);
        userBill.setFreezeTime(freezeTime);
        userBill.setMark("支付" + storeOrder.getPayPrice() + "元购买商品");
        //佣金
        userBill.setNumber(number);
        //余额
        userBill.setBalance(userService.getById(storeOrder.getUid()).getNowMoney());
        userBillService.save(userBill);
    }

    /**
     * 支付成功之后 - 发送模板消息通知
     * @author Mr.Zhang
     * @since 2020-07-01
     */
    private void pushTempMessage(StoreOrder storeOrder) {
        String tempKey = Constants.WE_CHAT_PUBLIC_TEMP_KEY_ORDER_PAY_SUCCESS;
        String type = Constants.PAY_TYPE_WE_CHAT_FROM_PUBLIC;
        if(Constants.ORDER_PAY_CHANNEL_PROGRAM == storeOrder.getIsChannel()){
            tempKey = Constants.WE_CHAT_PROGRAM_TEMP_KEY_ORDER_PAY_SUCCESS;
            type = Constants.PAY_TYPE_WE_CHAT_FROM_PROGRAM;
        }

        HashMap<String, String> map = new HashMap<>();
        map.put(Constants.WE_CHAT_TEMP_KEY_FIRST, "订单支付成功");
        map.put("orderId", storeOrder.getOrderId());
        map.put("payAmount", storeOrder.getPayPrice().toString());
        map.put(Constants.WE_CHAT_TEMP_KEY_END, "感谢购买！");

        templateMessageService.push(tempKey, map, storeOrder.getUid(), type);
    }

    /**
     * 支付成功之后 - 商品购买后根据配置送券
     * @param storeOrder
     */
    private void autoSendCoupons(StoreOrder storeOrder){
        // 根据订单详情获取商品信息
//        List<StoreOrderInfoVo> orders = storeOrderInfoService.getOrderListByOrderId(storeOrder.getId());
//        if(null == orders){
//            return;
//        }
//        for (StoreOrderInfoVo order : orders) {
//            List<StoreProductCoupon> couponsForGiveUser = storeProductCouponService.getListByProductId(order.getProductId());
//            if(CollectionUtils.isNotEmpty(couponsForGiveUser)) {
//                for (StoreProductCoupon storeProductCoupon : couponsForGiveUser) {
//                    StoreCouponUserRequest crp = new StoreCouponUserRequest();
//                    crp.setUid(storeOrder.getUid() + "");
//                    crp.setCouponId(storeProductCoupon.getIssueCouponId());
//                    storeCouponUserService.receive(crp);
//                }
//            }
//        }
    }

    /**
     * 支付成功之后 - 更新用户下单数量
     */
    private void updateUserPayCount(StoreOrder storeOrder) {
        userService.userPayCountPlus(userService.getById(storeOrder.getUid()));
    }


    /**
     * 支付成功之后 - 更新用户积分经验
     */
    private void updateFounds(StoreOrder storeOrder) {
        userService.consumeAfterUpdateUserFounds(storeOrder.getUid(), storeOrder.getId().toString(), storeOrder.getPayPrice(), Constants.USER_BILL_TYPE_PAY_ORDER);
    }

    /**
     * 检测是否未支付
     * @author Mr.Zhang
     * @since 2020-06-22
     */
    private Boolean checkOrderUnPay() {
        if(null == getOrder()){
        	log.error("--------------- 没有找到订单信息 ---------------");
        	return false;
        }

        if(getOrder().getPaid() || 0 != getOrder().getStatus()){
        	log.error("--------------- 当前操作被禁止，订单已经被处理 ---------------", getOrder().getId());
        	return false;
        }
        
    	return true;
    }

    /**
     * 获取订单详情数据
     * @author Mr.Zhang
     * @since 2020-06-22
     * @return List<StoreOrderInfoVo>
     */
    private List<StoreOrderInfoVo> getStoreOrderInfoList(){
        //商品信息
        return storeOrderInfoService.getOrderListByOrderId(getOrder().getId());
    }

    /**
     * 获取订单产品名称
     * @author Mr.Zhang
     * @since 2020-06-22
     * @return String
     */
    private String getProductName(){

        List<StoreOrderInfoVo> orderList = getStoreOrderInfoList();
        if(orderList.size() < 1){
            throw new CrmebException("在订单里没有找到商品数据");
        }
//        return orderList.get(0).getInfo().getJSONObject("productInfo").getString("store_name");
        return orderList.get(0).getInfo().getProductInfo().getStoreName();
    }


    private void pushBuyerOrder(StoreOrder storeOrder){
        logger.info("使用已有线程池【ChannelStoreOrderThreadPool——buyer】............");
        //推送buyer订单
        storeOrderFactory.pushOrder(storeOrder, BarCodeEnum.BUYER, true);

    }



    private void pushEuropeOrder(StoreOrder storeOrder){
        ChannelStoreOrderThreadPool.getInstance().execute(new Runnable() {
            @Override
            public void run() {
                logger.info("使用已有线程池【ChannelStoreOrderThreadPool——欧洲】............");
                //推送欧洲订单
                storeOrderFactory.pushOrder(storeOrder, BarCodeEnum.EUROPE, true);
            }
        });
    }

}
